﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Proyecta.Data.Helpers
{
    /// <summary>
    /// Representa a todas las sentencias JOIN que pueden ser utilizadas
    /// en una consulta SQL.
    /// </summary>
    /// <remarks>En esta clase se puede observar que se utilizo el patron
    /// de diseno Facade, al implementar los metodos Add de la clase QueryConditions
    /// con los metodos On.</remarks>
    public class QueryJoin : IGenerableQuery
    {
        public JoinType Tipo { get; set; }
        public string Tabla { get; set; }
        public string Alias { get; set; }
        public QueryConditions Condiciones { get; set; }

        private Query Query { get; set; }

        internal QueryJoin(Query query)
        {
            this.Query = query;
            this.Condiciones = new QueryConditions(query);
        }

        public Query On(params QueryCondition[] condiciones)
        {
            return this.Condiciones.Add(condiciones);
        }

        public Query On(string exp1, CompareOperator comparacion, string exp2)
        {
            return this.Condiciones.Add(exp1, comparacion, exp2);
        }

        public Query On(bool negar, string exp1, CompareOperator comparacion, string exp2)
        {
            return this.Condiciones.Add(LogicOperator.And, negar, exp1, comparacion, exp2);
        }

        public Query On(LogicOperator operador, string exp1, CompareOperator comparacion, string exp2)
        {
            return this.On(operador, false, exp1, comparacion, exp2);
        }

        public Query On(LogicOperator operador, bool negar, string exp1, CompareOperator comparacion, string exp2)
        {
            QueryCondition cond = new QueryCondition();
            cond.Operador = operador;
            cond.Negar = negar;
            cond.Expresion1 = exp1;
            cond.Comparacion = comparacion;
            cond.Expresion2 = exp2;
            return this.Condiciones.Add(cond);
        }

        public void Generate(StringBuilder sql)
        {
            sql.Append(Enum.GetName(this.Tipo.GetType(), this.Tipo).ToUpper());
            sql.Append(" JOIN ");
            sql.Append(this.Tabla);
            if (!string.IsNullOrEmpty(this.Alias)) sql.Append(" AS " + this.Alias);
            sql.AppendLine();

            if (this.Condiciones.Count > 0)
            {
                sql.Append("\tON ");
                this.Condiciones.Generate(sql);
                sql.AppendLine();
            }
        }
    }
}